package test.hbase;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: laoyu
 * @Date: 2020/6/8 11:54
 * @Description:
 */
public class HbaseDemo {
    static Configuration conf = HBaseConfiguration.create();


    //列出hbase中所有的表-->list
    public static void listTable() throws IOException {
        System.out.println(conf);
        //创建数据库连接
        Connection conn = ConnectionFactory.createConnection(conf);
        //Admin用来管理hbase数据库管的表信息
        Admin admin = conn.getAdmin();
        System.out.println("列出HBase中所有的表：");
        for (TableName tableName : admin.listTableNames()) {
            System.out.println(tableName);
        }
        //关闭数据库连接
        conn.close();
    }


    //查看表结构——describe 表名
    public static void describeTable(String tableName) throws IOException {
        //创建数据库连接
        Connection conn = ConnectionFactory.createConnection(conf);
        //Admin用来管理hbase数据库管的表信息
        Admin admin = conn.getAdmin();

        //要查看表结构的表名
        TableName tn = TableName.valueOf(tableName);
        //获取列族的集合
        ColumnFamilyDescriptor[] familyDescriptors = admin.getDescriptor(tn).getColumnFamilies();
        //遍历列族
        for (ColumnFamilyDescriptor family : familyDescriptors) {
            System.out.println(family.getNameAsString());
        }
        //关闭数据库连接
        conn.close();
    }


    //删除表——如果存在就删除，但是必须先禁用该表
    public static boolean removeTable(String tableName) throws IOException {
        Connection conn = ConnectionFactory.createConnection(conf);
        Admin admin = conn.getAdmin();
        TableName tn = TableName.valueOf(tableName);

        boolean flag = false;
        //判断表是否存在
        if (admin.tableExists(tn)) {
            //先禁用后删除
            admin.disableTable(tn);
            System.out.println("该表已被禁用……");
            admin.deleteTable(tn);
            System.out.println("该表已被删除！");
            flag = true;
        } else {
            System.err.println(tableName + "表不存在！");
            flag = false;
        }
        conn.close();
        return flag;
    }


    //创建表——如果表已经存在，则先删除再创建 create 表名 列族1,列族2……
    public static void createTable(String tableName, String... familyNames) throws IOException {
        Connection conn = ConnectionFactory.createConnection(conf);
        Admin admin = conn.getAdmin();
        TableName tn = TableName.valueOf(tableName);

        //判断表是否存在
        if (admin.tableExists(tn)) {
            //先禁用后删除
            admin.disableTable(tn);
            admin.deleteTable(tn);
        }

        //创建集合用于存放ColumnFamilyDescriptor对象
        List<ColumnFamilyDescriptor> familyDescriptor = new ArrayList<ColumnFamilyDescriptor>();
        for (String family : familyNames) {
            familyDescriptor.add(ColumnFamilyDescriptorBuilder.newBuilder(family.getBytes()).build());
        }

        //构建TableDescriptor对象，以保存tableName与familyNames
        TableDescriptor tableDescriptor = TableDescriptorBuilder
                .newBuilder(TableName.valueOf(tableName))
                .setColumnFamilies(familyDescriptor).build();

        //创建表
        System.out.println("==================开始创建" + tableName + "...........................");
        admin.createTable(tableDescriptor);
        System.out.println(tableName + "表创建完成！表结构如下：");
        System.out.println("===============================================");
        describeTable(tableName);
        System.out.println("===============================================");

        //关闭数据库连接
        conn.close();
    }


    //插入数据
    public static void putData(String tableName, String rowKey, String colKey, String colName, String colValue) throws IOException {
        Connection conn = ConnectionFactory.createConnection(conf);
        //创建表
        Table table = conn.getTable(TableName.valueOf(tableName));

        //添加数据
        Put p = new Put(Bytes.toBytes(rowKey));
        p.addColumn(Bytes.toBytes(colKey), Bytes.toBytes(colName), Bytes.toBytes(colValue));
        table.put(p);

        //关闭数据库连接
        conn.close();
    }


    //根据行键获取数据
    public static void getData(String tableName, String rowKey) throws IOException {
        Connection conn = ConnectionFactory.createConnection(conf);
        Table tb = conn.getTable(TableName.valueOf(tableName));

        //
        Get get = new Get(Bytes.toBytes(rowKey));
        Result result = tb.get(get);

        System.out.println(String.format("result.value=%s,result.toString:%s"
                , Bytes.toString(result.value()), result));
        conn.close();

    }

    //根据行键、列键获取数据
    public static void getData(String tableName, String rowKey, String colKey) throws IOException {
        Connection conn = ConnectionFactory.createConnection(conf);
        Table tb = conn.getTable(TableName.valueOf(tableName));

        //
        Get get = new Get(Bytes.toBytes(rowKey));
        get.addFamily(Bytes.toBytes(colKey));
        Result result = tb.get(get);

        System.out.println(String.format("result.value=%s,result.toString:%s"
                , Bytes.toString(result.value()), result));
        conn.close();

    }

    //根据行键、列键、修饰符获取数据
    public static void getData(String tableName, String rowKey, String colKey, String qualifier) throws IOException {
        Connection conn = ConnectionFactory.createConnection(conf);
        Table tb = conn.getTable(TableName.valueOf(tableName));

        //
        Get get = new Get(Bytes.toBytes(rowKey));
        get.addColumn(Bytes.toBytes(colKey), Bytes.toBytes(qualifier));
        Result result = tb.get(get);

        System.out.println(String.format("result.value=%s,result.toString:%s"
                , Bytes.toString(result.value()), result));
        conn.close();

    }


    //全表扫描
    public static void scanTable(String tableName) throws IOException {
        Connection conn = ConnectionFactory.createConnection(conf);
        Table tb = conn.getTable(TableName.valueOf(tableName));

        ResultScanner scanner = tb.getScanner(new Scan());
        System.out.println("============================================================================");
        for (Result row : scanner) {
            for (Cell cell : row.listCells()) {
                System.out.print(Bytes.toString(CellUtil.cloneRow(cell)));
                System.out.print("\t"+Bytes.toString(CellUtil.cloneFamily(cell)));
                System.out.print("\t"+Bytes.toString(CellUtil.cloneQualifier(cell)));
                System.out.print("\t"+Bytes.toString(CellUtil.cloneValue(cell))+"\n");
            }
        }
        System.out.println("============================================================================");
    }


    public static void main(String[] args) throws IOException {
//        listTable();
//        describeTable("music");
//        removeTable("scores");
//        createTable("scores", "grade", "course");
//
//        putData("scores", "jason", "course", "math", "90");
//        putData("scores", "jason", "course", "art", "80");
//        putData("scores", "jason", "grade", "", "1");
//        putData("scores", "blue", "course", "math", "77");
//        putData("scores", "blue", "course", "art", "88");
//        putData("scores", "blue", "grade", "", "2");

//        getData("scores","blue","course","math");
        scanTable("music");

    }
}
